import os, argparse, string, re, sys, shutil, time, vcd_read, fileinput
#systemC_tb_src_dir = "/user/rhp/work/soc_ip/imgworks/hw/soc_ip/noc_dram_perf/DEV/PLATO_EUROPA"
systemC_tb_src_dir = "/user/rhp/work/soc_ip/imgworks/hw/soc_ip/noc_dram_perf/MAIN"
sys.path.append(systemC_tb_src_dir + "/flexnoc_umctl2/testbench/scripts")
import createTestbench

# logging,
#logging.basicConfig(level=logging.INFO, format='%(asctime)s||| %(message)s')

#GRID_PREFIX = "do.grid -vmem 30000 -kew BETA -jobname simporter"
#GRID_PREFIX = ''

def chk_env_setup():
    #for envar in ['PROJECT_WORK', 'FLEXNOC_HOME', 'FLEXNOC_SHARE', 'INCISIV_VERSION'] :
    for envar in ['PROJECT_WORK', 'FLEXNOC_HOME', 'INCISIV_VERSION'] :
        if os.getenv(envar) == None :
            assert False, "ERROR: %s not set - please set %s before starting" % (envar,envar)
        else :
            print 'MSG:', envar + ' set to: ' + os.getenv(envar)
    print '\nMSG: Environment setup seems OK!' + '-'*10
    return os.getenv('PROJECT_WORK')


def run_command(calling_function_name, cmd, expected_return_codes=[0]) :
    print "\nExecuting command from: %s" % calling_function_name
    print ": %s" % cmd
    retcode = os.system(cmd)
    #assert retcode in expected_return_codes, 'Command did not return expected return code! ' + str(retcode) + ' ' + str(expected_return_codes) + cmd


def extract_scen_list(ss, sl):
    all_scenario_names = []
    prev_scenario = False
    for l in open(ss) :
        if prev_scenario :
            if 'def' in l :
                scenario_name = string.strip( re.sub('.* ', '', l[0:l.find('(')]) )
                all_scenario_names.append(scenario_name)
        if '@scenario' in l : prev_scenario = True
        else : prev_scenario = False
    ofp = open(sl, 'w')
    for ascen in all_scenario_names :
        print >> ofp, '-s', ascen
    ofp.close()
    print 'Wrote scenario names to', sl
    return all_scenario_names

    
def export_noc(noc_arch_name, sl, pdd, ss, dest_dir):
    scenarios = string.join([re.sub('\n','',l) for l in open(sl)], ' ')
#    logging.info('Scenarios ' + scenarios)
    run_command('export_noc', "FlexNoC64 -p %s importScript -f %s exportPlatform -a /%s %s -o %s" % (pdd, ss, noc_arch_name, scenarios, dest_dir))


def generate_base_tunefile(proj_name, noc_dir):
    os.chdir(noc_dir)
    run_command('generate_base_tunefile', "make -f Makefile.64")
    cmd = string.join(['./', proj_name, "_noc_spec_platform.64 -l > tune_base.txt"], '')
    run_command('generate_base_tunefile', cmd)
    run_command('generate_base_tunefile', "cp tune_base.txt $PROJECT_WORK/tests/tune.txt")
    #run_command("cp tune_base.txt tune.txt")


def generate_tb(proj_name, noc_arch_name, scen, run_dur, interleave, ddrc_src, ddrc_config, work_dir, noc_dir):

    def removeSignals(P):
        P["OtherDiscard"] = [n for n in P["OtherDiscard"] if n[0] not in (
            "dfi_rdlvl_en", "dfi_rdlvl_gate_en", "dfi_rdlvl_cs_n", "dfi_rdlvl_edge",
            "dfi_wrlvl_en", "dfi_wrlvl_cs_n", "dfi_wrlvl_strobe",)]
        P["OtherTieLow"] = [n for n in P["OtherTieLow"] if n[0] not in (
            "dfi_rdlvl_resp", "dfi_wrlvl_resp", )]

    createTestbench.createTestbench(
        projectName = proj_name, #"Europa",
        testbenchName = scen, #"GPU01_wronly_test_TB",
        scenarioName = scen, #"GPU01_wronly_test",
        nocSpecName = string.join([proj_name, 'noc', 'spec'], '_'),
        nocArchName = noc_arch_name, #string.join([proj_name, 'arch'], '_'),
        nrControllers = 2,
        nrAXIperController = 2,
        nrCSperController = 1,
        AXIDataBits = 128,
        AXIAddrBits = 32,
        AXIIdBits = 6,
        clockNames = ("noc_clk_hs", "noc_clk_cip3", "noc_clk_ms", "noc_clk_ls", "cpu0_initclk", "cpu0_targclk", "cpu1_initclk", "cpu1_targclk", "cpu2clk"),
        clockFreqsMHz = (600.0, 600.0, 400.0, 150.0, 600.0, 600.0, 500.0, 500.0, 600.0),
        resetNames = ("noc_resetn",),
        nocTargetPorts = (
          "ddr0_data0_targ_T",
          "ddr0_data1_targ_T",
          "ddr1_data0_targ_T",
          "ddr1_data1_targ_T",
          "cip2_0_targ_T",
          "cip2_1_targ_T",
          "cip3_mem_targ_T",
          "cip3_reg_targ_T",
          "cip4_reg_targ_T",        
          "cpu0_ic_targ_T",
          "cpu1_ic_targ_T",
          "cpu2_gic_targ_T",
          "ddr0_ctrl_targ_T",
          "ddr0_pub_targ_T",
          "ddr0_stats_targ_T",
          "ddr1_ctrl_targ_T",
          "ddr1_pub_targ_T",
          "ddr1_stats_targ_T",
          "display_targ_T",
          "ethernet_targ_T",
          "europa_always_on_socif_targ_T",
          "europa_switched_top_socif_targ_T",
          "gpu_targ_T",
          "isp_hispi0_targ_T",
          "isp_hispi1_targ_T",
          "isp_targ_T",
          "nand_targ_T",
          "otp_targ_T",
          "rom_targ_T",
          "rpu_targ_T",
          "sdhost0_targ_T",
          "sdhost1_targ_T",
          "sdhost2_targ_T",
          "sec_targ_T",
          "sfc0_targ_T",
          "sfc1_targ_T",
          "soc_if_targ_T",
          "sram_targ_T",
          "usb0_targ_T",
          "usb1_targ_T",
          "vpp_targ_T",
          "vxd_targ_T",
          "vxe_targ_T",
          ),
        nocInitiatorPorts = (
          "cip2_0_init_I",
          "cip2_1_init_I",
          "cip3_0_init_I",
          "cip3_1_init_I",
          "cip4_init_I",
          "cpu0_init_I",
          "cpu1_init_I",
          "cpu2_init_I",
          "display_init_I",
          "ethernet_init_I",
          "gpu_mem0_init_I",
          "gpu_mem1_init_I",
          "isp_init_I",
          "jtag_init_I",
          "mdc_init_I",
          "nand_init_I",
          "pdp0_init_I",
          "pdp1_init_I",
          "rpu_init_I",
          "sdhost0_init_I",
          "sdhost1_init_I",
          "sdhost2_init_I",
          "sec_init_I",
          "sfc0_init_I",
          "sfc1_init_I",
          "usb0_init_I",
          "usb1_init_I",
          "vpp_esm_init_I",
          "vpp_init_I",    
          "vxd_init_I",
          "vxe_init_I",
          ),
        mTrace = (),# tuples (portName, traceName, width, bool:is_master)
        sTrace = (),# tuples (portName, rdTraceName, wrTraceName)
        nocTieNames = ("loopback_bootmode_sel", "loopback_interleaved_sel", "tst_icg_bypass", "rom_write_en"),
        nocTieDefaults = (0, interleave, 0, 0),
        nocOutputs = (
          "FW_Bypass",
          "cip2_0_init_I_mainNoPendingTrans",
          "cip2_0_targ_T_mainPwrActive",
          "cip2_1_init_I_mainNoPendingTrans",
          "cip2_1_targ_T_mainPwrActive",
          "cip3_0_init_I_mainNoPendingTrans",
          "cip3_1_init_I_mainNoPendingTrans",
          "cip3_mem_targ_T_mainPwrActive",
          "cip3_reg_targ_T_mainPwrActive",
          "cip4_init_I_mainNoPendingTrans",
          "cip4_reg_targ_T_mainPwrActive",
          "cpu0_ic_targ_T_mainPwrActive",
          "cpu0_init_I_mainNoPendingTrans",
          "cpu1_ic_targ_T_mainPwrActive",
          "cpu1_init_I_mainNoPendingTrans",
          "cpu2_gic_targ_T_mainPwrActive",
          "cpu2_init_I_mainNoPendingTrans",
          "ddr0_ctrl_targ_T_mainPwrActive",
          "ddr0_data0_targ_T_mainPwrActive",
          "ddr0_data1_targ_T_mainPwrActive",
          "ddr0_pub_targ_T_mainPwrActive",
          "ddr0_stats_targ_T_mainPwrActive",
          "ddr1_ctrl_targ_T_mainPwrActive",
          "ddr1_data0_targ_T_mainPwrActive",
          "ddr1_data1_targ_T_mainPwrActive",
          "ddr1_pub_targ_T_mainPwrActive",
          "ddr1_stats_targ_T_mainPwrActive",
          "display_init_I_mainNoPendingTrans",
          "display_targ_T_mainPwrActive",
          "ethernet_init_I_mainNoPendingTrans",
          "ethernet0_targ_T_mainPwrActive",
          "europa_always_on_socif_targ_T_mainPwrActive",
          "europa_switched_top_control_socif_targ_T_mainPwrActive",
          "gpu0_init_I_mainNoPendingTrans",
          "gpu1_init_I_mainNoPendingTrans",
          "gpu_targ_T_mainPwrActive",
          "isp_hispi0_targ_T_mainPwrActive",
          "isp_hispi1_targ_T_mainPwrActive",
          "isp_init_I_mainNoPendingTrans",
          "isp_targ_T_mainPwrActive",
          "jtag_init_I_mainNoPendingTrans",
          "mdc_init_I_mainNoPendingTrans",
          "nand_init_I_mainNoPendingTrans",
          "nand_targ_T_mainPwrActive",
          "otp_targ_T_mainPwrActive",
          "pdp0_init_I_mainNoPendingTrans",
          "pdp1_init_I_mainNoPendingTrans",
          "rom_targ_T_mainPwrActive",
          "rpu_ctrl_targ_T_mainPwrActive",
          "rpu_init_I_mainNoPendingTrans",
          "sdhost0_init_I_mainNoPendingTrans",
          "sdhost0_targ_T_mainPwrActive",
          "sdhost1_init_I_mainNoPendingTrans",
          "sdhost1_targ_T_mainPwrActive",
          "sdhost2_init_I_mainNoPendingTrans",
          "sdhost2_targ_T_mainPwrActive",
          "sec_init_I_mainNoPendingTrans",
          "sec_targ_T_mainPwrActive",
          "secure_service_mainNoPendingTrans",
          "service_network_mainNoPendingTrans",
          "sfc0_init_I_mainNoPendingTrans",
          'loopback_interleaved_reg',
          'loopback_ddr_channel_reg',
          'loopback_bootmode_reg',
          "sfc0_targ_T_mainPwrActive",
          "sfc1_init_I_mainNoPendingTrans",
          "sfc1_targ_T_mainPwrActive",
          "soc_if_targ_T_mainPwrActive",
          "sram_targ_T_mainPwrActive",
          "tst_rst_bypass",
          "usb0_init_I_mainNoPendingTrans",
          "usb0_targ_T_mainPwrActive",
          "usb1_init_I_mainNoPendingTrans",
          "usb1_targ_T_mainPwrActive",
          "vpp_esm_mainNoPendingTrans",
          "vpp_init_I_mainNoPendingTrans",
          "vpp_targ_T_mainPwrActive",
          "vxd_init_I_mainNoPendingTrans",
          "vxd_targ_T_mainPwrActive",
          "vxe_init_I_mainNoPendingTrans",
          "vxe_targ_T_mainPwrActive",
          'noc_interrupt',
          'noc_firewall_error',
          'jtag_init_mainNoPendingTrans',
          'cpu1_init_mainNoPendingTrans',
          'cpu0_init_mainNoPendingTrans',
          'vxe_loopback_IOCU_reqinfo_02',
          'vxe_loopback_IOCU_reqinfo_01',
          'vxe_loopback_IOCU_reqinfo_00',
          'vxd_loopback_IOCU_reqinfo_02',
          'vxd_loopback_IOCU_reqinfo_01',
          'vxd_loopback_IOCU_reqinfo_00',
          'vpp_loopback_IOCU_reqinfo_02',
          'vpp_loopback_IOCU_reqinfo_01',
          'vpp_loopback_IOCU_reqinfo_00',
          'vpp_esm_loopback_IOCU_reqinfo_02',
          'vpp_esm_loopback_IOCU_reqinfo_01',
          'vpp_esm_loopback_IOCU_reqinfo_00',
          'usb1_loopback_IOCU_reqinfo_02',
          'usb1_loopback_IOCU_reqinfo_01',
          'usb1_loopback_IOCU_reqinfo_00',
          'usb0_loopback_IOCU_reqinfo_02',
          'usb0_loopback_IOCU_reqinfo_01',
          'usb0_loopback_IOCU_reqinfo_00',
          'sfc1_loopback_IOCU_reqinfo_02',
          'sfc1_loopback_IOCU_reqinfo_01',
          'sfc1_loopback_IOCU_reqinfo_00',
          'sfc0_loopback_IOCU_reqinfo_02',
          'sfc0_loopback_IOCU_reqinfo_01',
          'sfc0_loopback_IOCU_reqinfo_00',
          'sec_loopback_IOCU_reqinfo_02',
          'sec_loopback_IOCU_reqinfo_01',
          'sec_loopback_IOCU_reqinfo_00',
          'sdhost2_loopback_IOCU_reqinfo_02',
          'sdhost2_loopback_IOCU_reqinfo_01',
          'sdhost2_loopback_IOCU_reqinfo_00',
          'sdhost1_loopback_IOCU_reqinfo_02',
          'sdhost1_loopback_IOCU_reqinfo_01',
          'sdhost1_loopback_IOCU_reqinfo_00',
          'sdhost0_loopback_IOCU_reqinfo_02',
          'sdhost0_loopback_IOCU_reqinfo_01',
          'sdhost0_loopback_IOCU_reqinfo_00',
          'rpu_loopback_IOCU_reqinfo_02',
          'rpu_loopback_IOCU_reqinfo_01',
          'rpu_loopback_IOCU_reqinfo_00',
          'pdp1_loopback_IOCU_reqinfo_02',
          'pdp1_loopback_IOCU_reqinfo_01',
          'pdp1_loopback_IOCU_reqinfo_00',
          'pdp0_loopback_IOCU_reqinfo_02',
          'pdp0_loopback_IOCU_reqinfo_01',
          'pdp0_loopback_IOCU_reqinfo_00',
          'nand_loopback_IOCU_reqinfo_02',
          'nand_loopback_IOCU_reqinfo_01',
          'nand_loopback_IOCU_reqinfo_00',
          'mdc_loopback_IOCU_reqinfo_02',
          'mdc_loopback_IOCU_reqinfo_01',
          'mdc_loopback_IOCU_reqinfo_00',
          'jtag_loopback_IOCU_reqinfo_02',
          'jtag_loopback_IOCU_reqinfo_01',
          'jtag_loopback_IOCU_reqinfo_00',
          'isp_loopback_IOCU_reqinfo_02',
          'isp_loopback_IOCU_reqinfo_01',
          'isp_loopback_IOCU_reqinfo_00',
          #'gpu_mem1_loopback_IOCU_reqinfo_02',
          #'gpu_mem1_loopback_IOCU_reqinfo_01',
          #'gpu_mem1_loopback_IOCU_reqinfo_00',
          #'gpu_mem0_loopback_IOCU_reqinfo_02',
          #'gpu_mem0_loopback_IOCU_reqinfo_01',
          #'gpu_mem0_loopback_IOCU_reqinfo_00',
          'ethernet_loopback_IOCU_reqinfo_02',
          'ethernet_loopback_IOCU_reqinfo_01',
          'ethernet_loopback_IOCU_reqinfo_00',
          'display_loopback_IOCU_reqinfo_02',
          'display_loopback_IOCU_reqinfo_01',
          'display_loopback_IOCU_reqinfo_00',
          'cpu2_loopback_IOCU_reqinfo_02',
          'cpu2_loopback_IOCU_reqinfo_01',
          'cpu2_loopback_IOCU_reqinfo_00',
          'cpu1_loopback_IOCU_reqinfo_02',
          'cpu1_loopback_IOCU_reqinfo_01',
          'cpu1_loopback_IOCU_reqinfo_00',
          'cpu0_loopback_IOCU_reqinfo_02',
          'cpu0_loopback_IOCU_reqinfo_01',
          'cpu0_loopback_IOCU_reqinfo_00',
          'cip4_loopback_IOCU_reqinfo_02',
          'cip4_loopback_IOCU_reqinfo_01',
          'cip4_loopback_IOCU_reqinfo_00',
          'cip3_1_loopback_IOCU_reqinfo_02',
          'cip3_1_loopback_IOCU_reqinfo_01',
          'cip3_1_loopback_IOCU_reqinfo_00',
          'cip3_0_loopback_IOCU_reqinfo_02',
          'cip3_0_loopback_IOCU_reqinfo_01',
          'cip3_0_loopback_IOCU_reqinfo_00',
          'cip2_1_loopback_IOCU_reqinfo_02',
          'cip2_1_loopback_IOCU_reqinfo_01',
          'cip2_1_loopback_IOCU_reqinfo_00',
          'cip2_0_loopback_IOCU_reqinfo_02',
          'cip2_0_loopback_IOCU_reqinfo_01',
          'cip2_0_loopback_IOCU_reqinfo_00',
          'vxe_loopback_ddr_data_sel',
          'vxd_loopback_ddr_data_sel',
          'vpp_loopback_ddr_data_sel',
          'vpp_esm_loopback_ddr_data_sel',
          'usb1_loopback_ddr_data_sel',
          'usb0_loopback_ddr_data_sel',
          'sfc1_loopback_ddr_data_sel',
          'sfc0_loopback_ddr_data_sel',
          'sec_loopback_ddr_data_sel',
          'sdhost2_loopback_ddr_data_sel',
          'sdhost1_loopback_ddr_data_sel',
          'sdhost0_loopback_ddr_data_sel',
          'rpu_loopback_ddr_data_sel',
          'pdp1_loopback_ddr_data_sel',
          'pdp0_loopback_ddr_data_sel',
          'nand_loopback_ddr_data_sel',
          'mdc_loopback_ddr_data_sel',
          'isp_loopback_ddr_data_sel',
          'ethernet_loopback_ddr_data_sel',
          'display_loopback_ddr_data_sel',
          'cpu2_loopback_ddr_data_sel',
          'cpu1_loopback_ddr_data_sel',
          'cpu0_loopback_ddr_data_sel',
          'cip4_loopback_ddr_data_sel',
          'cip3_1_loopback_ddr_data_sel',
          'cip3_0_loopback_ddr_data_sel',
          'cip2_1_loopback_ddr_data_sel',
          'cip2_0_loopback_ddr_data_sel',          
          #'default_read_secid_00',
          #'default_read_secid_01',
          #'default_read_secid_02',
          #'default_read_secid_03',
          #'default_read_secid_04',
          #'default_read_secid_05',
          #'default_read_secid_06',
          #'default_read_secid_07',
          #'default_read_secid_08',
          #'default_read_secid_09',
          #'default_read_secid_10',
          #'default_read_secid_11',
          #'default_read_secid_12',
          #'default_read_secid_13',
          #'default_read_secid_14',
          #'default_read_secid_15',
          #'default_read_secid_16',
          #'default_read_secid_17',
          #'default_read_secid_18',
          #'default_read_secid_19',
          #'default_read_secid_20',
          #'default_read_secid_21',
          #'default_read_secid_22',
          #'default_read_secid_23',
          #'default_read_secid_24',
          #'default_read_secid_25',
          #'default_read_secid_26',
          #'default_read_secid_27',
          #'default_read_secid_28',
          #'default_read_secid_29',
          #'default_read_secid_30',
          #'default_read_secid_31',
          #'default_write_secid_00',
          #'default_write_secid_01',
          #'default_write_secid_02',
          #'default_write_secid_03',
          #'default_write_secid_04',
          #'default_write_secid_05',
          #'default_write_secid_06',
          #'default_write_secid_07',
          #'default_write_secid_08',
          #'default_write_secid_09',
          #'default_write_secid_10',
          #'default_write_secid_11',
          #'default_write_secid_12',
          #'default_write_secid_13',
          #'default_write_secid_14',
          #'default_write_secid_15',
          #'default_write_secid_16',
          #'default_write_secid_17',
          #'default_write_secid_18',
          #'default_write_secid_19',
          #'default_write_secid_20',
          #'default_write_secid_21',
          #'default_write_secid_22',
          #'default_write_secid_23',
          #'default_write_secid_24',
          #'default_write_secid_25',
          #'default_write_secid_26',
          #'default_write_secid_27',
          #'default_write_secid_28',
          #'default_write_secid_29',
          #'default_write_secid_30',
          #'default_write_secid_31',
          #'FW_default_read_secid',
          #'FW_default_write_secid',    
          'noc_cpu2_interrupt',
          'noc_cpu1_interrupt',
          'noc_cpu0_interrupt'
          ),
        axiType = "sc_bv",
        XPI_RAQD_LG2 = 3,
        UMCTL2_WDATARAM_AW = 7,
        PhyRdLat = 7,
        defaultDurationS = run_dur, #1e-5,
        signalTrace = "uMCTL2Signals",
        verilogAlias = ddrc_src,
        verilogBase = ddrc_src, #"/projects/ipsource/europa/ip_cores/ddr/umctl/config3",
        verilogSources = string.join(["/projects/europa/ref/ip_cores/ddr/umctl/config6_v16/", "src/DWC_ddr_umctl2.lst"], ''),
        arterisExportDir = "../../src/noc_systemc_regress", #noc_dir,
        uMCTL2InitialiserName = ddrc_config, #"../../src/umctl2_soft_config/config_Europa_DDR4",
        workDir = work_dir,
        arterisInstall = "/vl/edatools/extern/Arteris/flexnoc/FlexNoC-2.11.2/",
        windup = removeSignals,
        StatsPeriodUs = 110,#
        enableTrace = 1,
        #buildFlags = "-debug",
        #runFlags = "-gui -access r",
    )


#    for line in fileinput.input(firun, inplace=1):
#        print "I AM HEREERERERE"
#        print line.replace('alias.*', '')
#    fileinput.close()
#    print "I AM DONEEEEEE"
#            f.write(re.sub('alias.*',''))
#    with open(firun, 'r') as f:
#        lines = f.readlines()
#        for l in lines:
#            l = l.replace('alias', '')
#            f.write(l)
#    f.close()

def compile_tb(work_dir, scen, grid_prefix):
    firun = string.join([scen, '.irun'], '')
    firun_mod = scen + '_mod' + '.irun'
    os.chdir(work_dir)
    ofw = open(firun_mod, 'w')
    for l in open(firun):
        ofw.write(re.sub('alias.*', '', l))
    ofw.close()        
    cirun = string.join([grid_prefix, 'source', firun_mod], ' ')
    run_command('compile_tb', cirun)
    #os.chdir(work_dir)
    #os.system(cirun)

def compile_av(work_dir):
    cmake = 'make -f Makefile.64'
    os.chdir(work_dir)
    run_command('compile_av', cmake)

#def run_av(noc_spec_name, scen, run_dur, work_dir, tune_file):
def run_av(noc_spec_name, scen, run_dur, work_dir, interleave, tune_file):
    base_av = './' + noc_spec_name + '_platform.64'
    av_opts = {}
    av_opts['-d'] = run_dur
    av_opts['-s'] = scen
    av_opts['-t'] = scen
    av_opts['-j'] = scen + '_j'
    av_opts['-jp'] = ''
    av_opts['-p'] = 'loopback_interleaved_sel' + '=' + str(interleave)
    av_opts['-f'] = tune_file
    av_opts['-x'] = scen + '.xml'
    base_opts = ''
    for key in av_opts:
        base_opts = string.join([base_opts, key, av_opts[key]])
    cmd = base_av + base_opts
    os.chdir(work_dir)
    #print cmd
    run_command('run_av', cmd)

def run_tb(scen, run_dur, work_dir, tune_file, grid_prefix):
    sc_key = '+systemc_args+'
    #base_grid = 'echo $PYTHONPATH; do.grid -jobname simporter -kew BETA -vmem 24000 -slots 1 --l Incisive_HDL_Simulator__OR__Incisive_Enterprise_Simulator__AND__VERILOG-XL -do'
    #base_grid = 'do.grid -jobname simporter -kew BETA -vmem 24000 -slots 1 --l Incisive_HDL_Simulator__OR__Incisive_Enterprise_Simulator__AND__VERILOG-XL -do'
    base_grid = ''
    irun_log  = '-l ' + scen + '.log'
    base_irun = 'irun -R -64bit -override_precision -timescale 1ns/1ps ' + irun_log
    sc_args = {}
    sc_args['+systemc_args+-t' ] = string.join([sc_key, scen, '_t'], '')
    sc_args['+systemc_args+-j' ] = string.join([sc_key, scen, '_j'], '')
    sc_args['+systemc_args+-jp'] = ''
    sc_args['+systemc_args+-x' ] = string.join([sc_key, scen, '.xml'], '')
    sc_args['+systemc_args+-d' ] = string.join([sc_key, run_dur], '')
    sc_args['+systemc_args+-f' ] = string.join([sc_key, tune_file], '')
    base_sc = ''
    for key in sc_args:
        base_sc = string.join([base_sc, key, sc_args[key]], ' ')
    cmd = string.join([grid_prefix, base_irun, base_sc], ' ')
    os.chdir(work_dir)
    run_command('run_tb', cmd)


#def analyse_vcd(work_dir, grid_prefix):
#    os.chdir(work_dir)
#    cmd = grid_prefix + ' ' + 'python vcd_read.py'
#    run_command('analyse_vcd', cmd)
   

def parse_irun_xml(irun_xml_file) :
    import xml.etree.ElementTree as ET
    tree = ET.parse(irun_xml_file)
    queues = tree.findall('queue')
    processes = tree.findall('process')
    processes = map(lambda x:{k:v for k,v in x.items()}, processes)
    queues = map(lambda x:{k:v for k,v in x.items()}, queues)
    return processes, queues
    #assert len(processes) == len(queues)
    rows = []
    for pn, qn in zip(processes, queues) :
        row = {}
        #if qn.get('name').lower() not in pn.get('name').lower() :
        #    raise Exception('Mapping between process and queue nodes should be reworked ' + pn.get('name') + ' ' + qn.get('name'))
        for k,v in pn.items() : row[k] = v
        #for k in ['averageVolume', 'averageLatency'] : row[k] = qn.get(k)
        rows.append(row)
    return rows


def parse_irun_log(irun_log_file) :
    testname = None
    test_re = re.compile('.systemc_args.*_t')
    table = {}
    for l in open(irun_log_file).readlines() :
        if test_re.search(l) :
            assert testname == None, 'Test name should be unique... ' + testname
            testname = re.sub('.systemc_args.', '', string.strip(l))
    return testname


def write_process_table_to_excel(given_rows, xlfile) :
    headers = set()
    for arow in given_rows :
        for k in arow.keys() : headers.add(k)
    headers = list(headers)
    for k in reversed(['name','bandwidth','expected','efficiency',]) :
        assert k in headers
        headers.remove(k)
        headers = [k] + headers
    rows = []
    for arow in given_rows :
        row = []
        for k in headers :
            try : row.append( arow[k] )
            except KeyError : row.append( None )
        rows.append(row)
    import tablib
    results = tablib.Dataset(headers=headers)
    for r in rows : results.append(r)
    results.append(['']*len(rows[0]))
    for r in rows : results.append(r)
    results.append(['']*len(rows[0]))
    ofp = open(xlfile,'w')
    print >> ofp, results.xlsx
    ofp.close()
    print 'Wrote file', xlfile


def iter_regression_matrix(iterators, all_scens, all_tunings, all_ddrc_configs, all_noc_archs, all_ddrc_archs):
    ddrc_archs   = [all_ddrc_archs[0]  ]
    noc_archs    = [all_noc_archs[0]   ]
    ddrc_configs = [all_ddrc_configs[0]]
    tunings      = [all_tunings[0]     ]
    scens        = [all_scens[0]       ]

    for iterator in iterators:
        if iterator == 'ddrcArch':
            ddrc_archs   = all_ddrc_archs
        if iterator == 'nocArch':
            noc_archs    = all_noc_archs
        if iterator == 'ddrcConfig':
            ddrc_configs = all_ddrc_configs
        if iterator == 'tunings':
            tunings      = all_tunings
        if iterator == 'scenarios':
            scens        = all_scens

    test_inst = {}
    for ddrc_arch in ddrc_archs:
        for noc_arch in noc_archs:
            for ddrc_config in ddrc_configs:
                for tuning in tunings:
                    for scen in scens:
                        test_inst['DDRC_ARCH'  ] = ddrc_arch
                        test_inst['NOC_ARCH'   ] = noc_arch
                        test_inst['DDRC_CONFIG'] = ddrc_config
                        test_inst['TUNING'     ] = tuning
                        test_inst['SCEN'       ] = scen
                        yield test_inst

    
def main() :
    PROJECT_WORK = chk_env_setup()

    parser = argparse.ArgumentParser(prog='PROG')
    subparsers = parser.add_subparsers(dest='command', help='this script can be used to run and analyse performance at NoC level or at system level')

    #parser for arteris only (ao) environment runs
    parser_ao = subparsers.add_parser('ao', help='run and analyse in arteris only environment (at the NOC level)')
    group_ao = parser_ao.add_mutually_exclusive_group(required=True)
    group_ao.add_argument("--regress_ao", dest='regress_ao', nargs='+', choices=['scenarios', 'tunings'], help='run a regression in arteris only environment')
    group_ao.add_argument("--singleScenario", dest='scen', help='name of the scenario to run')
    

    #parser for systemC (sc) environment runs
    parser_sc = subparsers.add_parser('sc', help='run and analyse in systemC environment (at the system level')
    parser_sc.add_argument("--regress_sc", nargs='+', choices=['scenarios', 'tunings', 'ddrcConfig', 'nocArch', 'ddrcArch'], help='run in systemC environment and regress over one or more of these')

    parser.add_argument("--export", dest ='export', type=int, default=0, help='bit to indicate if AV model should be newly exported and compiled for this run (1= export and compile): default = 0')
    parser.add_argument("--projectName", dest='proj', default='europa', help='name of the project')
    parser.add_argument("--scenarioScript", dest='ss', default=PROJECT_WORK+'tests/europaFlexNoCScenarios_shortlist_usecases.py', help='path to the scenario script')
    parser.add_argument("--scenarioList", dest='sl', default=PROJECT_WORK+'tests/scenarios_regress.lst', help='path to the file in which to store the extracted list of scenarios')
    parser.add_argument("--pdd", dest='pdd', default=PROJECT_WORK+'../flexnoc/europa_noc.pdd', help='path to the noc pdd')
    parser.add_argument("--nocExportDir", dest='noc_dir', default=PROJECT_WORK+'src/noc_systemc_regress', help='directory in which to export the NoC AV model')
    parser.add_argument("--runDuration", dest='run_dur', default='1e-4', help='duration for which to run this test in seconds: default = 1e-5')
    parser.add_argument("--interleave", type=int, default=1, help='bit to select interleaved(=1) or non-interleaved(=0) mode of operation: default = 1')
    parser.add_argument("--ddrcSrc", dest='ddrc_src', default='/projects/ipsource/europa/ip_cores/ddr/umctl/config6_v16', help='DDRC source config')
    parser.add_argument("--ddrcRegConfig", dest='ddrc_config', default=PROJECT_WORK+'src/umctl2_soft_config/config_Europa_DDR4', help='path to the file containing DDRC register configuration')
    parser.add_argument("--workDir", dest='work_dir', default=PROJECT_WORK+'sim/regress', help='path to the work directory')
    parser.add_argument("--genBaseTuneFile", dest ='gen_tune', type=int, default=1, help='bit to indicate if the base tune file needs to be regenerated(1=generate): default = 1')
    parser.add_argument("--tuningFile", dest='tune_file', default=PROJECT_WORK+'tests/tune.txt', help='path to the NoC tuning file')
    parser.add_argument("--gridPrefix", dest='grid_prefix', default="do.grid -vmem 30000 -kew BETA -jobname simporter", help='uses grid by default set to empty string for not using the grid')


    args = parser.parse_args()
    #print parser.parse_args()

    noc_arch_name = args.proj + '_arch'
    noc_spec_name = args.proj + '_noc_spec'
    vcd_filename  = args.work_dir + '/europa_noc_spec_signals.vcd' #'/uMCTL2Signals.vcd'

    results = {}
    res = []
    scen_list = []
    
    all_scens = extract_scen_list(args.ss, args.sl)
    if args.export == 1 :
        if os.path.isdir(args.noc_dir) :
            print 'MSG: deleting directory', args.noc_dir
            shutil.rmtree(args.noc_dir)
            os.mkdir(args.noc_dir)
            print 'MSG: created directory', args.noc_dir
        export_noc(noc_arch_name, args.sl, args.pdd, args.ss, args.noc_dir)
        if args.gen_tune == 1:
            generate_base_tunefile(args.proj, args.noc_dir)
    
    if args.command=='ao' :
        if args.export == 1 :
            compile_av(args.noc_dir)
        if args.scen:
            run_av(noc_spec_name, args.scen, args.run_dur, args.noc_dir, args.interleave, args.tune_file)
        else:
            f = open(args.sl, 'r')
            for line in f:
                scen = re.split('-s (.*)\n', line)
                scen_list.append(scen[1])
            for s in scen_list:
                run_av(noc_spec_name, s, args.run_dur, args.noc_dir, args.interleave, args.tune_file)
                #irun_xml_file = args.noc_dir + '/' + s + '.xml'
            	#process_results, queue_results = parse_irun_xml(irun_xml_file)        
            	#results[s] = {"input":test_inst, "processes": process_results, "queues": queue_results, "stalls":stall_results}
        print 'I am exploring!!!'
        sys.exit(0)
    else :
        print ' I am regressing!!!!'
        for test_inst in iter_regression_matrix(iterators=args.regress_sc, all_scens=all_scens, all_tunings=[args.tune_file], all_ddrc_configs=[args.ddrc_config], all_noc_archs=[noc_arch_name], all_ddrc_archs=[args.ddrc_src]):
            results[test_inst['SCEN']] = 'FAILED'
            try :
            	#for adir in [args.work_dir] :
                #        if os.path.isdir(adir) :
                #            print 'MSG: deleting directory', adir
                #            shutil.rmtree(adir)
                #            os.mkdir(adir)
                #            print 'MSG: created directory', adir
            	#if 'nocArch' in args.regress:
            	#    export_noc(test_inst['NOC_ARCH'], args.sl, args.pdd, args.ss, args.noc_dir)        
            	#    if args.gen_tune == 1:
            	#        generate_base_tunefile(args.proj, args.noc_dir)
            	generate_tb(args.proj, test_inst['NOC_ARCH'], test_inst['SCEN'], args.run_dur, args.interleave, test_inst['DDRC_ARCH'], test_inst['DDRC_CONFIG'], args.work_dir, args.noc_dir)
            	compile_tb(args.work_dir, test_inst['SCEN'], args.grid_prefix)
            	run_tb(test_inst['SCEN'], args.run_dur, args.work_dir, test_inst['TUNING'], args.grid_prefix)
                #vcd_filename = args.work_dir + '/' + test_inst['SCEN'] + '_t.vcd'
            	stall_results = vcd_read.parse_vcd(vcd_filename)
            	#irun_xml_file = '/user/rhp/work/europa/rachana.pandit_europa_DEV_NOC_ws/hw/europa/DEV/NOC_BETA/noc/performance/sim/work/' + test_inst['SCEN'] + '.xml'
            	irun_xml_file = args.work_dir + '/' + test_inst['SCEN'] + '.xml'
                run_command('copy xml', 'cp irun_xml_file ./results/all_usecases/.')
            	process_results, queue_results = parse_irun_xml(irun_xml_file)        
            	results[test_inst['SCEN']] = {"input":test_inst, "processes": process_results, "queues": queue_results, "stalls":stall_results}
            except Exception, e :
                print 'NOTE'*5, e

    print results
    
    #with open("results.txt", 'w') as f:
    #    f.write(results)
        
    ofp = open('results.pkl','w')
    import cPickle
    cPickle.dump(results,ofp)
    ofp.close()
    #write_process_table_to_excel(res , '/user/afl/OPEN/summary.xlsx' )        


    

if __name__=='__main__' :
    main() ; sys.exit(0)
